home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / stream.h < prev    next >
C/C++ Source or Header  |  1999-05-14  |  10KB  |  331 lines

  1. // $Id: stream.h,v 1.3 1999/01/25 20:00:31 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef stream_INCLUDED
  11. #define stream_INCLUDED
  12.  
  13. #include "config.h"
  14. #include <sys/stat.h>
  15. #include <limits.h>
  16. #include <iostream.h>
  17. #include <stddef.h>
  18. #include <stdio.h>
  19. #include "javadef.h"
  20. #include "javasym.h"
  21. #include "tuple.h"
  22. #include "bool.h"
  23. #include "tab.h"
  24. #include "lookup.h"
  25. #include "unicode.h"
  26.  
  27. class Control;
  28. class Input_info;
  29. class Scanner;
  30. class Symbol;
  31. class FileSymbol;
  32. class ZipFile;
  33.  
  34. class StreamError
  35. {
  36. public:
  37.     enum StreamErrorKind
  38.     {
  39.         BAD_TOKEN,
  40.         BAD_OCTAL_CONSTANT,
  41.         EMPTY_CHARACTER_CONSTANT,
  42.         UNTERMINATED_CHARACTER_CONSTANT,
  43.         UNTERMINATED_COMMENT,
  44.         UNTERMINATED_STRING_CONSTANT,
  45.         INVALID_HEX_CONSTANT,
  46.         INVALID_FLOATING_CONSTANT_EXPONENT,
  47.         INVALID_UNICODE_ESCAPE
  48.     };
  49.  
  50.     unsigned start_location,
  51.              end_location;
  52.     StreamErrorKind kind;
  53.  
  54.     void Initialize(StreamErrorKind kind_, unsigned start_location_, unsigned end_location_)
  55.     {
  56.         kind = kind_;
  57.         start_location = start_location_;
  58.         end_location = end_location_;
  59.  
  60.         return;
  61.     }
  62. };
  63.  
  64.  
  65. //
  66. // LexStream holds a stream of tokens generated from an input and 
  67. // provides methods to retrieve information from the stream.
  68. //
  69. class LexStream
  70. {
  71. public:
  72.     typedef int TypeIndex;
  73.     typedef int TokenIndex;
  74.     typedef int CommentIndex;
  75.     enum { INFINITY = INT_MAX }; // the largest possible value for TokenIndex
  76.  
  77.     FileSymbol *file_symbol;
  78.  
  79.     inline TokenIndex Next(TokenIndex i)
  80.          { return (++i < token_stream.Length() ? i : token_stream.Length() - 1); }
  81.  
  82.     inline TokenIndex Previous(TokenIndex i) { return (i <= 0 ? 0 : i - 1); }
  83.  
  84.     inline TokenIndex Peek() { return Next(index); }
  85.  
  86.     inline void Reset(TokenIndex i = 1) { index = Previous(i); }
  87.  
  88.     inline TokenIndex Gettoken() { return index = Next(index); }
  89.  
  90.     inline TokenIndex Gettoken(TokenIndex end_token)
  91.          { return index = (index < end_token ? Next(index) : token_stream.Length() - 1); }
  92.  
  93.     inline TokenIndex Badtoken() { return 0; }
  94.  
  95.     inline unsigned Kind(TokenIndex i) { return tokens[i].Kind(); }
  96.  
  97.     inline unsigned Location(TokenIndex i) { return tokens[i].Location(); }
  98.  
  99.     inline unsigned Line(TokenIndex i) { return FindLine(tokens[i].Location()); }
  100.  
  101.     inline unsigned Column(TokenIndex i) { return columns ? columns[i] : (input_buffer ? FindColumn(tokens[i].Location()) : 0); }
  102.  
  103.     inline bool AfterEol(TokenIndex i) { return (i < 1 ? true : Line(i - 1) < Line(i)); }
  104.  
  105.     inline TokenIndex MatchingBrace(TokenIndex i) { return tokens[i].additional_info.right_brace; }
  106.  
  107.     inline Symbol *NameSymbol(TokenIndex i) { return (Kind(i) != TK_LBRACE ? tokens[i].additional_info.symbol : (Symbol *) NULL); }
  108.  
  109.     wchar_t *Name(TokenIndex i)
  110.     {
  111.         return (NameSymbol(i) ? tokens[i].additional_info.symbol -> Name() : KeywordName(tokens[i].Kind()));
  112.     }
  113.  
  114.     int NameLength(TokenIndex i)
  115.     {
  116.         return (NameSymbol(i) ? tokens[i].additional_info.symbol -> NameLength() : wcslen(KeywordName(tokens[i].Kind())));
  117.     }
  118.  
  119.     char *FileName();
  120.     int FileNameLength();
  121.  
  122.     inline int LineLength(unsigned line_no) { return locations[line_no + 1] - locations[line_no]; }
  123.     inline int LineStart(unsigned line_no)  { return locations[line_no]; }
  124.     inline int LineEnd(unsigned line_no)    { return locations[line_no + 1] - 1; }
  125.  
  126.     inline int LineSegmentLength(TokenIndex i)
  127.         { return Tab::Wcslen(input_buffer, tokens[i].Location(), LineEnd(Line(i))); }
  128.  
  129.     wchar_t *InputBuffer() { return input_buffer; }
  130.     size_t InputBufferLength() { return input_buffer_length; }
  131.  
  132.     CommentIndex FirstComment(TokenIndex);
  133.  
  134.     inline int NumTypes() { return type_index.Length(); }
  135.     inline TokenIndex Type(int i) { return types[i]; }
  136.  
  137.     inline int NumTokens() { return token_stream.Length(); }
  138.  
  139.     inline int NumComments() { return comment_stream.Length(); }
  140.  
  141.     inline TokenIndex PrecedingToken(CommentIndex i) { return comments[i].previous_token; }
  142.  
  143.     inline unsigned CommentLocation(CommentIndex i)  { return comments[i].location; }
  144.  
  145.     inline wchar_t *CommentString(CommentIndex i)    { return comments[i].string; }
  146.  
  147.     inline int CommentStringLength(CommentIndex i)   { return comments[i].length; }
  148.  
  149.     inline int NumBadTokens() { return bad_tokens.Length(); }
  150.  
  151. #ifdef TEST
  152.     int file_read;
  153. #endif
  154.  
  155.     //*
  156.     //* Constructors and Destructor.
  157.     //*
  158.     LexStream(Control &control_, FileSymbol *file_symbol_) : control(control_),
  159.                                                              file_symbol(file_symbol_),
  160.                                                              initial_reading_of_input(true),
  161.                                                              input_buffer(NULL),
  162.                                                              input_buffer_length(0),
  163.                                                              comment_buffer(NULL),
  164.                                                              token_stream(12, 16),
  165.                                                              tokens(NULL),
  166.                                                              columns(NULL),
  167.                                                              comment_stream(10, 8),
  168.                                                              comments(NULL),
  169.                                                              line_location(12, 8),
  170.                                                              locations(NULL)
  171. #ifdef TEST
  172.                                                            , file_read(0)
  173. #endif
  174.     {}
  175.  
  176.     bool ComputeColumns()
  177.     {
  178.         RereadInput();
  179.         if (input_buffer)
  180.             InitializeColumns();
  181.  
  182.         DestroyInput();
  183.  
  184.         return (columns != NULL);
  185.     }
  186.  
  187.     void RereadInput();
  188.     ~LexStream();
  189.  
  190.  
  191.     void DestroyInput()
  192.     {
  193.         delete [] input_buffer;
  194.         input_buffer = NULL;
  195.  
  196.         delete [] comment_buffer;
  197.         comment_buffer = NULL;
  198.     }
  199.  
  200.     void SortMessages();
  201.     void PrintMessages();
  202.     void PrintEmacsMessage(int);
  203.     void PrintSmallSource(int);
  204.     void PrintLargeSource(int);
  205.     void PrintMessage(StreamError::StreamErrorKind);
  206.  
  207.     void SetUpComments()
  208.     {
  209.         RereadInput();
  210.         //
  211.         // Calculate the length of the string required to save the comments.
  212.         // Allocate the buffer, save the comments in the buffer and update their
  213.         // respective "string" pointer.
  214.         //
  215.         int length = 0,
  216.             i;
  217.  
  218.         for (i = 1; i < comment_stream.Length(); i++)
  219.             length += (comments[i].length + 1);
  220.         comment_buffer = new wchar_t[length];
  221.         wchar_t *ptr = comment_buffer;
  222.         for (i = 1; i < comment_stream.Length(); i++)
  223.         {
  224.             memmove(ptr, &(input_buffer[comments[i].location]), comments[i].length * sizeof(wchar_t));
  225.             comments[i].string = ptr;
  226.             ptr += comments[i].length;
  227.             *ptr++ = U_NULL;
  228.         }
  229.  
  230.         return;
  231.     }
  232.  
  233. #ifdef TEST
  234. void LexStream::Dump(); // temporary function used to dump token stream.
  235. #endif
  236.  
  237.     //
  238.     // Return the total size of space allocated for the tokens.
  239.     //
  240.     size_t TokenSpaceAllocated(void)
  241.     {
  242.         return token_stream.Length() * sizeof(Token);
  243.     }
  244.  
  245.     //
  246.     // Return the total size of space allocated for the comments.
  247.     //
  248.     size_t CommentSpaceAllocated(void)
  249.     {
  250.         return comment_stream.Length() * sizeof(Comment);
  251.     }
  252.  
  253. private:
  254.  
  255.     friend class Scanner;
  256.  
  257.     class Token
  258.     {
  259.     public:
  260.         unsigned info;
  261.         union
  262.         {
  263.             Symbol   *symbol;
  264.             TokenIndex right_brace;
  265.         } additional_info;
  266.  
  267.         inline void SetLocation(unsigned location) { info = (info & 0x000000FF) | (location << 8); }
  268.         inline unsigned Location()                 { return (info >> 8); }